package com.gpscookie.mobile;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.EOFException;
import java.io.IOException;

import javax.microedition.rms.RecordComparator;
import javax.microedition.rms.RecordEnumeration;
import javax.microedition.rms.RecordFilter;
import javax.microedition.rms.RecordStore;
import javax.microedition.rms.RecordStoreException;
import javax.microedition.rms.RecordStoreNotOpenException;

import org.json.me.JSONArray;

import de.enough.polish.util.Locale;

public class RMSStore implements RecordFilter, RecordComparator
{
	public static int INVALIDID = -1;
	public static int filterKey = INVALIDID;
	public static RecordStore recordStore = null; 
	private static MemoryStore memoryStore = null;
	
	public static int USER = 10;
	public static int USERDBID = 11;
	public static int PWD = 12;
	public static int LAT = 21;
	public static int LON = 22;
	public static int TAG = 23;
	public static int REFRESHRATE = 30;
	public static int MISSIONDBID = 40;
	public static int MISSIONUUID = 41;
	public static int MISSIONSECRET = 42;
	public static int AD = 50;
	
	
	public static MemoryStore getMemoryStore() {
		return memoryStore;
	}

	public static void setMemoryStore(MemoryStore memoryVector) {
		RMSStore.memoryStore = memoryVector;
	}

	public RMSStore() {
		try {
		    recordStore = RecordStore.openRecordStore("gpscookie", true);
		}
		catch (RecordStoreException rse) {
		    System.out.println(rse);
		}		
	}
	
	public void close() {		
		try {
			saveMemoryStore();
			this.recordStore.closeRecordStore();
		} catch (RecordStoreNotOpenException e) {
		} catch (RecordStoreException e) {
		}
	}
	
    /*
     * Part of the RecordFilter interface.
     */
    public boolean matches(byte[] candidate) throws IllegalArgumentException
    {
		// If no filter set, nothing can match it.
		if (filterKey < 0) {
		    return false;
		}
	
		ByteArrayInputStream bais = new ByteArrayInputStream(candidate);
		DataInputStream inputStream = new DataInputStream(bais);
		String name = null;
		int key = filterKey +1;
		
		try {
			key = inputStream.readInt();
		    name = inputStream.readUTF();
		}
		catch (EOFException eofe) {
		    System.out.println(eofe);
		}
		catch (IOException eofe) {
		    System.out.println(eofe);
		}
		return (filterKey==key);
    }

    /*
     * Part of the RecordComparator interface.
     */
    public int compare(byte[] rec1, byte[] rec2)
    {
		// Construct DataInputStreams for extracting the scores from
		// the records.
		ByteArrayInputStream bais1 = new ByteArrayInputStream(rec1);
		DataInputStream inputStream1 = new DataInputStream(bais1);
		ByteArrayInputStream bais2 = new ByteArrayInputStream(rec2);
		DataInputStream inputStream2 = new DataInputStream(bais2);
		String score1 = "";
		String score2 = "";
		int key1 = this.INVALIDID;
		int key2 = this.INVALIDID;
		try {
		    // Extract the scores.
			key1 = inputStream1.readInt();
		    score1 = inputStream1.readUTF();
		    key2 = inputStream2.readInt();
		    score2 = inputStream2.readUTF();
		}
		catch (EOFException eofe) {
		    System.out.println(eofe);
		}
		catch (IOException eofe) {
		    System.out.println(eofe);
		}
	
		// Sort by value
		int rtn = score1.compareTo(score2);
		if (rtn < 0) {
		    return RecordComparator.PRECEDES;
		}
		else if (rtn > 0) {
		    return RecordComparator.FOLLOWS;
		}
		else {
		    return RecordComparator.EQUIVALENT;
		}
    }
    
    protected void putToRMS(int key, String value)
    {
		//
		// Each score is stored in a separate record, formatted with
		//
		ByteArrayOutputStream baos = new ByteArrayOutputStream();
		DataOutputStream outputStream = new DataOutputStream(baos);
		try {
			outputStream.writeInt(key);			
		    outputStream.writeUTF(value);
		}
		catch (IOException ioe) {
		    System.out.println(ioe);
		}
	
		// Extract the byte array
		byte[] b = baos.toByteArray();
		// Add it to the record store
		try {
			int recID = getRecordID(key);
			if (recID<0) {
				// new record
				recordStore.addRecord(b, 0, b.length);
			} else {
				// update a record
				recordStore.setRecord(recID, b, 0, b.length);
			}
		} catch (RecordStoreException rse) {
		    System.out.println(rse);
		}
    }
    
    protected int getRecordID(int key) {
    	filterKey = key;
    	try {
    	    // Enumerate the records using the comparator and filter
    	    // implemented above to sort by game score.
    	    RecordEnumeration re = recordStore.enumerateRecords(this, this, 
    								true);
    	    if (re != null && re.hasNextElement()) {
    	    	return re.nextRecordId();
    	    } else {
    	    	return -1;
    	    }
    	}
    	catch (Exception rse) {
    	    System.out.println(rse);
    	    rse.printStackTrace();
    	} 
    	return -1;
    }    

    protected String getFromRMS(int key, String defaultStr) {
    	filterKey = key;
    	try {
    	    // Enumerate the records using the comparator and filter
    	    // implemented above
    	    RecordEnumeration re = recordStore.enumerateRecords(this, this, 
    								true);
    	    if (re != null && re.hasNextElement()) {
    			ByteArrayInputStream bais1 = new ByteArrayInputStream(re.nextRecord());
    			DataInputStream inputStream1 = new DataInputStream(bais1);
    			inputStream1.readInt();
    	    	return inputStream1.readUTF();
    	    } else {
    	    	return defaultStr;
    	    }
    	}
    	catch (Exception rse) {
    	    System.out.println(rse);
    	} 
    	return defaultStr;
    }

    public void saveMemoryStore() {
    	putToRMS(USER, memoryStore.getValue(USER, ""));
    	putToRMS(USERDBID, memoryStore.getValue(USERDBID, ""));
    	putToRMS(PWD, memoryStore.getValue(PWD, ""));
    	putToRMS(LAT, memoryStore.getValue(LAT, ""));
    	putToRMS(LON, memoryStore.getValue(LON, ""));
    	putToRMS(TAG, memoryStore.getValue(TAG, ""));
    	putToRMS(REFRESHRATE, memoryStore.getValue(REFRESHRATE, ""));
    	putToRMS(MISSIONDBID, memoryStore.getValue(MISSIONDBID, ""));
    	putToRMS(MISSIONUUID, memoryStore.getValue(MISSIONUUID, ""));
    	putToRMS(MISSIONSECRET, memoryStore.getValue(MISSIONSECRET, ""));
    	putToRMS(AD, memoryStore.getValue(AD, Locale.get("AD")));
    }
    
	public void loadMemoryStore() {
		memoryStore.setValue(USER, this.getFromRMS(USER, ""));
		memoryStore.setValue(USERDBID, this.getFromRMS(USERDBID, ""));
		memoryStore.setValue(PWD, this.getFromRMS(PWD, ""));
		memoryStore.setValue(LAT, this.getFromRMS(LAT, "39.91"));
		memoryStore.setValue(LON, this.getFromRMS(LON, "116.41"));
		memoryStore.setValue(TAG, this.getFromRMS(TAG, ""));
		memoryStore.setValue(REFRESHRATE, this.getFromRMS(REFRESHRATE, "1"));
		memoryStore.setValue(MISSIONDBID, this.getFromRMS(MISSIONDBID, ""));
		memoryStore.setValue(MISSIONUUID, this.getFromRMS(MISSIONUUID, ""));
		memoryStore.setValue(MISSIONSECRET, this.getFromRMS(MISSIONSECRET, ""));
		memoryStore.setValue(AD, this.getFromRMS(AD, Locale.get("AD")));
	}

	public String get(int key, String defaultValue) {
		return memoryStore.getValue(key, defaultValue);
	}   
	
	public void put(int key, String value) {
		memoryStore.setValue(key, value);
	}
}
